"""
AI-SOES - 试卷管理系统
包含试卷模板、试卷生成、试卷分析等相关模型
"""
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from django.core.validators import MinValueValidator, MaxValueValidator
from decimal import Decimal

from apps.core.models import TimeStampedModel

User = get_user_model()


class ExamPaperTemplate(TimeStampedModel):
    """
    试卷模板
    用于定义试卷的基本结构和配置
    """
    name = models.CharField('模板名称', max_length=100)
    description = models.TextField('模板描述', blank=True)

    # 模板类型
    template_type = models.CharField(
        '模板类型',
        max_length=50,
        choices=[
            ('standard', '标准试卷'),
            ('adaptive', '自适应试卷'),
            ('random', '随机试卷'),
            ('fixed', '固定试卷'),
        ],
        default='standard'
    )

    # 模板配置 (JSON格式)
    template_config = models.JSONField(
        '模板配置',
        default=dict,
        help_text='试卷模板配置参数'
    )

    # 默认时长
    default_duration = models.PositiveIntegerField(
        '默认时长(分钟)',
        default=120,
        validators=[MinValueValidator(1), MaxValueValidator(720)]
    )

    default_total_score = models.DecimalField(
        '默认总分',
        max_digits=6,
        decimal_places=2,
        default=Decimal('100.00'),
        validators=[MinValueValidator(1)]
    )

    default_passing_score = models.DecimalField(
        '默认及格分',
        max_digits=6,
        decimal_places=2,
        default=Decimal('60.00'),
        validators=[MinValueValidator(0)]
    )

    # 使用次数
    usage_count = models.PositiveIntegerField('使用次数', default=0)

    # 创建者
    creator = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='paper_templates',
        verbose_name='创建者'
    )

    # 状态相关
    is_active = models.BooleanField('是否活跃', default=True)
    is_public = models.BooleanField('是否公开', default=False)

    class Meta:
        db_table = 'exam_paper_templates'
        verbose_name = '试卷模板'
        verbose_name_plural = '试卷模板'
        ordering = ['-usage_count', '-created_at']
        unique_together = [['name', 'creator']]

    def __str__(self):
        return f"{self.name} ({self.get_template_type_display()})"

    def increment_usage(self):
        """增加使用次数"""
        self.usage_count += 1
        self.save(update_fields=['usage_count'])


class ExamPaper(TimeStampedModel):
    """
    试卷
    具体的考试试卷实例
    """
    title = models.CharField('试卷标题', max_length=200)
    description = models.TextField('试卷描述', blank=True)

    # 关联模板
    template = models.ForeignKey(
        ExamPaperTemplate,
        on_delete=models.SET_NULL,
        related_name='exam_papers',
        verbose_name='试卷模板',
        null=True,
        blank=True
    )

    # 试卷类型
    paper_type = models.CharField(
        '试卷类型',
        max_length=50,
        choices=[
            ('formal', '正式考试'),
            ('practice', '练习考试'),
            ('mock', '模拟考试'),
            ('diagnostic', '诊断考试'),
        ],
        default='formal'
    )

    # 题目配置
    question_config = models.JSONField(
        '题目配置',
        default=dict,
        help_text='题目生成相关配置'
    )

    # 考试时长
    duration = models.PositiveIntegerField(
        '考试时长(分钟)',
        validators=[MinValueValidator(1), MaxValueValidator(720)]
    )

    total_score = models.DecimalField(
        '总分',
        max_digits=6,
        decimal_places=2,
        validators=[MinValueValidator(1)]
    )

    passing_score = models.DecimalField(
        '及格分',
        max_digits=6,
        decimal_places=2,
        validators=[MinValueValidator(0)]
    )

    # 试卷状态
    status = models.CharField(
        '状态',
        max_length=20,
        choices=[
            ('draft', '草稿'),
            ('generated', '已生成'),
            ('reviewed', '已审核'),
            ('published', '已发布'),
            ('archived', '已归档'),
        ],
        default='draft'
    )

    # 生成方法
    generation_method = models.CharField(
        '生成方法',
        max_length=50,
        choices=[
            ('manual', '手动创建'),
            ('auto', '自动生成'),
            ('template', '模板生成'),
            ('ai', 'AI生成'),
        ],
        default='manual'
    )

    # 题目列表 (JSON格式，包含题目ID和配置信息)
    questions = models.JSONField('题目列表', default=list)

    # 统计信息
    question_count = models.PositiveIntegerField('题目数量', default=0)
    average_difficulty = models.DecimalField('平均难度', max_digits=3, decimal_places=2, null=True)

    # 标签
    tags = models.JSONField('标签', default=list, blank=True)

    # 创建者
    creator = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='exam_papers',
        verbose_name='创建者'
    )

    # 审核者
    reviewer = models.ForeignKey(
        User,
        on_delete=models.SET_NULL,
        related_name='reviewed_papers',
        verbose_name='审核者',
        null=True,
        blank=True
    )

    # 审核时间
    reviewed_at = models.DateTimeField('审核时间', null=True, blank=True)

    # 审核备注
    review_notes = models.TextField('审核备注', blank=True)

    # 使用次数
    usage_count = models.PositiveIntegerField('使用次数', default=0)

    # 是否公开
    is_public = models.BooleanField('是否公开', default=False)

    class Meta:
        db_table = 'exam_papers'
        verbose_name = '试卷'
        verbose_name_plural = '试卷'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['status']),
            models.Index(fields=['paper_type']),
            models.Index(fields=['creator']),
            models.Index(fields=['is_public']),
        ]

    def __str__(self):
        return self.title

    def calculate_statistics(self):
        """计算试卷统计信息"""
        if not self.questions:
            self.question_count = 0
            self.average_difficulty = None
            self.save(update_fields=['question_count', 'average_difficulty'])
            return

        # 这里应该根据实际的题目列表计算统计信息
        # 暂时使用默认值
        self.question_count = len(self.questions)
        self.average_difficulty = Decimal('3.5')  # 默认平均难度

        self.save(update_fields=['question_count', 'average_difficulty'])

    def generate_from_template(self, template, question_bank=None, **kwargs):
        """从模板生成试卷"""
        # 复制模板的基本配置
        self.template = template
        self.generation_method = 'template'

        # 更新配置
        config = template.template_config.copy()
        config.update(kwargs)

        self.question_config = config
        self.duration = config.get('duration', template.default_duration)
        self.total_score = config.get('total_score', template.default_total_score)
        self.passing_score = config.get('passing_score', template.default_passing_score)

        # 生成题目列表
        # 这里应该根据配置生成具体的题目
        self.questions = []  # 暂时为空

        self.save()
        self.calculate_statistics()

        # 增加模板使用次数
        template.increment_usage()


class PaperSection(TimeStampedModel):
    """
    试卷部分
    试卷的各个部分/章节
    """
    exam_paper = models.ForeignKey(
        ExamPaper,
        on_delete=models.CASCADE,
        related_name='sections',
        verbose_name='试卷'
    )

    name = models.CharField('部分名称', max_length=100)
    description = models.TextField('部分描述', blank=True)
    instructions = models.TextField('说明文字', blank=True)

    # 部分配置
    section_config = models.JSONField('部分配置', default=dict)

    # 题目范围
    start_question = models.PositiveIntegerField('开始题号', default=1)
    end_question = models.PositiveIntegerField('结束题号', default=0)

    # 部分分数
    section_score = models.DecimalField(
        '部分分数',
        max_digits=6,
        decimal_places=2,
        validators=[MinValueValidator(0)]
    )

    # 时间限制 (可选)
    time_limit = models.PositiveIntegerField(
        '时间限制(分钟)',
        null=True,
        blank=True,
        help_text='可选，如果设置则覆盖试卷总时长'
    )

    # 排序序号
    order = models.PositiveIntegerField('排序序号', default=0)

    class Meta:
        db_table = 'paper_sections'
        verbose_name = '试卷部分'
        verbose_name_plural = '试卷部分'
        ordering = ['exam_paper', 'order', 'id']
        unique_together = [['exam_paper', 'name']]

    def __str__(self):
        return f"{self.exam_paper.title} - {self.name}"

    @property
    def question_count(self):
        """题目数量"""
        if self.end_question >= self.start_question:
            return self.end_question - self.start_question + 1
        return 0


class PaperQuestion(TimeStampedModel):
    """
    试卷题目
    试卷与题目的关联关系
    """
    exam_paper = models.ForeignKey(
        ExamPaper,
        on_delete=models.CASCADE,
        related_name='paper_questions',
        verbose_name='试卷'
    )

    section = models.ForeignKey(
        PaperSection,
        on_delete=models.SET_NULL,
        related_name='paper_questions',
        verbose_name='试卷部分',
        null=True,
        blank=True
    )

    # 关联题目
    question = models.ForeignKey(
        'question_bank.Question',
        on_delete=models.CASCADE,
        related_name='paper_questions',
        verbose_name='题目'
    )

    # 题目序号
    question_number = models.PositiveIntegerField('题号')

    # 题目分数
    score = models.DecimalField(
        '分数',
        max_digits=6,
        decimal_places=2,
        validators=[MinValueValidator(0)]
    )

    # 题目配置 (JSON格式)
    question_config = models.JSONField('题目配置', default=dict, blank=True)

    # 排序序号
    order = models.PositiveIntegerField('排序序号', default=0)

    class Meta:
        db_table = 'paper_questions'
        verbose_name = '试卷题目'
        verbose_name_plural = '试卷题目'
        ordering = ['exam_paper', 'order', 'question_number']
        unique_together = [['exam_paper', 'question_number']]
        indexes = [
            models.Index(fields=['exam_paper', 'question']),
            models.Index(fields=['exam_paper', 'section']),
        ]

    def __str__(self):
        return f"{self.exam_paper.title} - 第{self.question_number}题"


class PaperAnalysis(TimeStampedModel):
    """
    试卷分析
    对试卷进行的各种分析
    """
    exam_paper = models.OneToOneField(
        ExamPaper,
        on_delete=models.CASCADE,
        related_name='analysis',
        verbose_name='试卷'
    )

    # 难度分析
    difficulty_distribution = models.JSONField('难度分布', default=dict)
    average_difficulty = models.DecimalField('平均难度', max_digits=3, decimal_places=2, null=True)

    # 知识点覆盖
    knowledge_coverage = models.JSONField('知识点覆盖', default=dict)
    coverage_score = models.DecimalField('覆盖率分数', max_digits=3, decimal_places=2, null=True)

    # 题型分布
    type_distribution = models.JSONField('题型分布', default=dict)

    # 质量指标
    quality_score = models.DecimalField('质量分数', max_digits=3, decimal_places=2, null=True)
    discrimination_index = models.DecimalField('区分度', max_digits=3, decimal_places=2, null=True)

    # 时间指标
    estimated_time = models.PositiveIntegerField('预估完成时间(分钟)', null=True)

    # 改进建议
    improvement_suggestions = models.JSONField('改进建议', default=list, blank=True)

    # 分析状态
    analysis_status = models.CharField(
        '分析状态',
        max_length=20,
        choices=[
            ('pending', '待处理'),
            ('processing', '处理中'),
            ('completed', '已完成'),
            ('failed', '失败'),
        ],
        default='pending'
    )

    # 分析时间
    analyzed_at = models.DateTimeField('分析时间', null=True, blank=True)

    class Meta:
        db_table = 'paper_analysis'
        verbose_name = '试卷分析'
        verbose_name_plural = '试卷分析'

    def __str__(self):
        return f"{self.exam_paper.title} - 分析结果"

    def analyze(self):
        """执行试卷分析"""
        self.analysis_status = 'processing'
        self.save(update_fields=['analysis_status'])

        try:
            # 这里应该实现具体的分析逻辑
            # 暂时使用默认值
            self.difficulty_distribution = {
                'easy': 0.3,
                'medium': 0.5,
                'hard': 0.2
            }
            self.average_difficulty = Decimal('3.5')

            self.type_distribution = {
                'choice': 0.4,
                'fill_blank': 0.2,
                'essay': 0.3,
                'programming': 0.1
            }

            self.quality_score = Decimal('4.2')
            self.estimated_time = self.exam_paper.duration or 120

            self.analysis_status = 'completed'
            self.analyzed_at = timezone.now()
            self.save(update_fields=[
                'difficulty_distribution', 'average_difficulty',
                'type_distribution', 'quality_score', 'estimated_time',
                'analysis_status', 'analyzed_at'
            ])

        except Exception as e:
            self.analysis_status = 'failed'
            self.save(update_fields=['analysis_status'])
            raise e


class PaperVersion(TimeStampedModel):
    """
    试卷版本
    试卷的版本历史记录
    """
    exam_paper = models.ForeignKey(
        ExamPaper,
        on_delete=models.CASCADE,
        related_name='versions',
        verbose_name='试卷'
    )

    version_number = models.CharField('版本号', max_length=20)
    version_notes = models.TextField('版本说明', blank=True)

    # 版本快照 (JSON格式，包含完整的试卷数据)
    paper_snapshot = models.JSONField('试卷快照', default=dict)

    # 变更记录
    changes = models.JSONField('变更记录', default=list)

    # 创建者
    created_by = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='paper_versions',
        verbose_name='创建者'
    )

    # 是否为当前版本
    is_current = models.BooleanField('是否当前版本', default=False)

    class Meta:
        db_table = 'paper_versions'
        verbose_name = '试卷版本'
        verbose_name_plural = '试卷版本'
        ordering = ['-created_at']
        unique_together = [['exam_paper', 'version_number']]

    def __str__(self):
        return f"{self.exam_paper.title} v{self.version_number}"

    def save(self, *args, **kwargs):
        # 如果是当前版本，则将其他版本设为非当前
        if self.is_current:
            PaperVersion.objects.filter(
                exam_paper=self.exam_paper,
                is_current=True
            ).update(is_current=False)

        super().save(*args, **kwargs)